package youdu

import (
	"crypto/tls"
	"encoding/json"
	"fmt"
	"net/http"
	"vidii"

	"github.com/jmoiron/sqlx"

	_ "github.com/go-sql-driver/mysql"
)

// User 定义用户结构体
type table_t_trust struct {
	Buin    int    `db:"buin"`
	Secret  string `db:"secret"`
	Dnshost string `db:"dnshost"`
	Dnsport int    `db:"dnsport"`
}

func (o *Sso) SaveSecret() error {
	// 向mysql的 emoa_auth 库 t_trust 表写入 secret
	if o.Secret == "" {
		return fmt.Errorf("secret不能为空")
	}
	// 数据库连接配置
	connStr := fmt.Sprintf("%s:%s@tcp(%s:%s)/emoa_auth?parseTime=true",
		o.YouduDBUser,
		o.YouduDBPassword,
		o.YouduDBServer,
		o.YouduDBPort)
	db, err := sqlx.Open("mysql", connStr)
	if err != nil {
		return fmt.Errorf("有度数据库连接失败：%s", err.Error())
	}
	defer db.Close()

	// 测试数据库连接
	err = db.Ping()
	if err != nil {
		return fmt.Errorf("有度数据库测试失败：%s", err.Error())
	}
	// 构造新的 auth 数据，o.Server 值是个url，可能是 https/http 请提取出域名和端口号
	urlObj, err := vidii.Http.ParseURL(o.Server)
	if err != nil {
		return fmt.Errorf("URL解析失败：%s", err.Error())
	}
	newAuth := table_t_trust{
		Buin:    o.Buin,
		Secret:  o.Secret,
		Dnshost: urlObj.Domain,
		Dnsport: urlObj.Port,
	}
	// 查询是否存在该 secret 的数据
	var auth table_t_trust
	err = db.Get(&auth, "SELECT * FROM t_trust WHERE secret = ?", o.Secret)
	if err != nil {
		// return fmt.Errorf("查询SSO密钥数据失败：%s", err.Error())
		// 执行插入操作
		query := `INSERT INTO t_trust (buin, secret, dnshost, dnsport)
			VALUES (:buin, :secret, :dnshost, :dnsport)`
		_, err = db.NamedExec(query, newAuth)
		if err != nil {
			return fmt.Errorf("插入SSO密钥数据失败：%s", err.Error())
		}
		return nil
	}

	// 如果存在记录就更新
	query := `UPDATE t_trust SET
			buin = :buin,
			dnshost = :dnshost,
			dnsport = :dnsport
			WHERE secret = :secret`
	_, err = db.NamedExec(query, newAuth)
	if err != nil {
		// 注意语法，where 之前不应该有逗号
		return fmt.Errorf("更新SSO密钥数据失败：%s", err.Error())
	}

	return nil
}

func (o *Sso) GetLoginLink(userId string) (string, error) {
	// 参数验证
	if userId == "" {
		return "", fmt.Errorf("userId不能为空")
	}

	// 构造请求URL
	url := fmt.Sprintf("%s/v3/api/jginfo/getloginkey?secret=%s&account=%s",
		o.Server,
		o.Secret,
		userId)

	// 忽略证书
	tr := &http.Transport{
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
	}
	client := &http.Client{
		Transport: tr,
	}

	// 发送GET请求
	resp, err := client.Get(url)
	if err != nil {
		return "", fmt.Errorf("请求登录key失败：%s", err.Error())
	}
	defer resp.Body.Close()

	// 解析响应
	type ResponseData struct {
		Status struct {
			Code      int    `json:"code"`
			Message   string `json:"message"`
			CreatedAt string `json:"createdAt"`
		} `json:"status"`
		Token string `json:"token"`
	}

	if resp.StatusCode != 200 {
		return "", fmt.Errorf("请求返回失败状态：%s", resp.Status)
	}

	var result ResponseData
	err = json.NewDecoder(resp.Body).Decode(&result)
	if err != nil {
		// 可能返回空body
		return "", fmt.Errorf("解析响应数据失败：%s", err.Error())
	}

	// 检查响应状态
	if result.Status.Code != 0 {
		return "", fmt.Errorf("获取Token失败：%s", result.Status.Message)
	}

	return fmt.Sprintf("yd://ssologin?token=%s", result.Token), nil
}
